//
// Created by TNJ on 2021/6/9.
//

#include <stdio.h>
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>

void stack_init(_stack_t *s, int capacity){
    if(s == NULL || capacity <= 0){
        return;
    }

    s->arr = (int *)malloc(capacity * sizeof(int));
    s->front = 0;
    s->size = 0;
    s->cap = capacity;
}

void stack_push(_stack_t *s, int data){
    if(s == NULL){
        return;
    }
    if(stack_is_full(s)){
        return;
    }
    s->size++;
    s->arr[s->front++] = data;
}

int stack_pop(_stack_t *s){
    if(s == NULL){
        return NAN;
    }
    if(stack_is_empty(s)){
        return NAN;
    }
    s->size--;
    return s->arr[--s->front];
}

int stack_size(_stack_t *s){
    if(s == NULL){
        return 0;
    }
    return s->size;
}

bool stack_is_empty(_stack_t *s){
    if(s == NULL){
        return true;
    }
    return s->size > 0 ? false : true;
}

bool stack_is_full(_stack_t *s){
    if(s == NULL){
        return false;
    }
    return s->size == s->cap ? true : false;
}

void stack_destroy(_stack_t *s){
    if(s == NULL){
        return;
    }
    if(s->arr){
        free(s->arr);
    }
    s->arr = NULL;
    s->cap = 0;
    s->size = 0;
    s->front = 0;
}

//以下是用链表实现栈
stack_linked_t *new_stack_linked_node(int data){
    return new_list_node(data);
}

void stack_linked_push(stack_linked_t **s, int data){
    //这里一定要注意分开两个if，因为或运算符的特性
    if(s == NULL){
        return;
    }
    if(*s == NULL){
        return;
    }
    //采用头插法插入链表
    *s = list_add(*s, data);
}

int stack_linked_pop(stack_linked_t **s){
    //这里一定要注意分开两个if，因为或运算符的特性
    if(s == NULL){
        return NAN;
    }
    if(*s == NULL){
        return NAN;
    }

    stack_linked_t *stack_node = get_list_head(s);
    int data = stack_node->data;
    free(stack_node);
    return data;
}

int stack_linked_size(stack_linked_t *s){
    if(s == NULL){
        return 0;
    }

    return list_length(s);
}

bool stack_linked_is_empty(stack_linked_t *s){
    if(s == NULL){
        return true;
    }

    return list_length(s) > 0 ? false : true;
}

void stack_linked_destroy(stack_linked_t **s){
    if(s == NULL){
        return;
    }
    if(*s == NULL){
        return;
    }

    list_destroy(*s);
    *s = NULL;
}